/*
 * 注册基础node => 添加锚点/图标 => 绘制node => 初始化node状态 => node动画(设置交互动画)
 * auth:lala
 */
import itemEvents from './item-event'
import anchorEvent from './anchor-event'
import { ext } from '@antv/matrix-util'

const transform = ext.transform
export default G6 => {
  G6.registerNode('base-node-image', {
    draw(cfg, group) {
      const attrs = cfg
      const { width, height } = attrs.style
      const img = attrs.baseUrl
      const id = cfg.id
      let rotate = attrs.rotate
      const shape = group.addShape('rect', {
        attrs: {
          x: -width / 2,
          y: -height / 2,
          width,
          height,
          fill: '#fff',
          radius: 4
        },
        name: 'node-rect',
        className: `node-rect`,
        rotateTag: 0,
        draggable: true
      })
      const imgGroup = group.addShape('image', {
        attrs: {
          ...attrs,
          x: -width / 2,
          y: -height / 2,
          width,
          height,
          img,
          size: [width, height]
        },
        name: 'node-img',
        className: `node-img`,
        draggable: true
      })

      // 按className查找元素
      group.getItem = className => {
        return group.get('children').find(item => item.get('className') === className)
      }

      let ids = localStorage.getItem('ids')
      if (ids) {
        ids = JSON.parse(ids)
        for (const idsKey in ids) {
          if (idsKey === id) {
            rotate = ids[idsKey]
          }
          // const node = group.findById(idsKey)
          // console.log(node)
        }
      }
      console.log('rotate :' + rotate)
      if (rotate && rotate !== 0) {
        /* let matrix = imgGroup.getMatrix()
        if (!matrix) matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1]
        const rotateRate = (Number(rotate) / 360) * (2 * Math.PI)
        // 3*3 矩阵变换，用于二维渲染
        const newMatrix = transform(matrix, [
          ['r', rotateRate] // rotate
        ])*/
        imgGroup && imgGroup.resetMatrix()
        shape && shape.resetMatrix()
        imgGroup.rotate(rotate)
        shape.rotate(rotate)
      }

      shape.attr({
        rotateTag: rotate
      })

      group.addRotateIcon = () => {
        let shapeControlRotate = group.getItem('shapeControlRotate')
        if (shapeControlRotate) {
          group.removeRotateIcon()
        }
        const img = require('@/assets/rotate.png')
        const nodeRect = group.getItem('node-rect')
        const radian = nodeRect.attrs.rotateTag || 0
        const rotateW = 20
        const rotateH = 20
        shapeControlRotate = group.addShape('image', {
          name: 'shapeControlRotate',
          tag: 'shapeControlRotate',
          className: 'shapeControlRotate',
          attrs: {
            ...attrs,
            boxName: 'shapeControl',
            name: 'shapeControlRotate',
            x: -rotateW / 2,
            y: -height / 2 - 40,
            width: rotateW,
            height: rotateH,
            cursor: 'crosshair',
            img,
            size: [rotateW, rotateH],
            // 默认样式
            opacity: 0
          }
        })
        setTimeout(() => {
          shapeControlRotate.attr({
            opacity: 1
          })
          shapeControlRotate && shapeControlRotate.resetMatrix()
          shapeControlRotate.rotate(radian)
        }, 100)
      }
      group.removeRotateIcon = () => {
        const icons = group.get('children').filter(item => item.get('className') === 'shapeControlRotate')
        if (icons && icons.length) {
          icons.forEach(icon => {
            console.log('删除rotate ============ ', icon)
            icon && icon.remove()
          })
        }
      }

      // 添加锚点
      this.initAnchor(cfg, group)
      return shape
    },
    /* afterDraw(cfg, group) {
      let ids = localStorage.getItem('ids')
      if (ids) {
        ids = JSON.parse(ids)
        for (const idsKey in ids) {
          const node = group.findById(idsKey)
        }
      }
    },*/
    // 绘制锚点
    initAnchor(cfg, group) {
      group.anchorShapes = []
      group.showAnchor = group => {
        this.drawAnchor(cfg, group)
      }
      group.clearAnchor = group => {
        group.anchorShapes && group.anchorShapes.forEach(a => a.remove())
        group.anchorShapes = []
      }
    },
    drawAnchor(cfg, group) {
      const { type, direction, anchorPointStyles } = group.getFirst().attr()
      const item = group.get('children')[0]
      const bBox = item.getBBox()
      const anchors = this.getAnchorPoints(cfg)

      // 绘制锚点坐标
      anchors && anchors.forEach((p, i) => {
        const diff = type === 'triangle-node' ? (direction === 'up' ? 1 : 0) : 0.5
        const x = bBox.width * (p[0] - 0.5)
        const y = bBox.height * (p[1] - diff)

        /**
         * 绘制三层锚点
         * 最底层: 锚点bg
         * 中间层: 锚点
         * 最顶层: 锚点group, 用于事件触发
         */
        const anchorPointStylesNew = anchorPointStyles || {
          fill: '#fff',
          lineWidth: 1,
          r: 4,
          stroke: '#1890FF'
        }
        // 视觉锚点
        const anchor = group.addShape('circle', {
          attrs: {
            x,
            y,
            ...anchorPointStylesNew
          },
          zIndex: 1,
          nodeId: group.get('id'),
          className: 'node-anchor',
          draggable: false,
          isAnchor: true,
          index: i
        })

        // 锚点事件触发的元素
        const anchorGroup = group.addShape('circle', {
          attrs: {
            x,
            y,
            r: 8,
            fill: '#80b9f2',
            opacity: 0
          },
          zIndex: 2,
          nodeId: group.get('id'),
          className: 'node-anchor-group',
          draggable: true,
          isAnchor: true,
          index: i
        })

        /**
         * ! 添加锚点事件绑定
         */
        anchorEvent(anchorGroup, group, p)

        group.anchorShapes.push(anchor)
        group.anchorShapes.push(anchorGroup)
      })

      // const { height } = cfg.style

      group.getBashedLine = () => {
        return group.findAllByName('dashed-line')
      }
      // 查找所有锚点
      group.getAllAnchors = () => {
        return group.anchorShapes.filter(c => c.get('isAnchor') === true)
      }
      // 查找指定锚点
      group.getAnchor = (i) => {
        return group.anchorShapes.filter(c => c.get('className') === 'node-anchor' && c.get('index') === i)
      }
      // 查找所有锚点背景
      group.getAllAnchorBg = () => {
        return group.anchorShapes.filter(c => c.get('className') === 'node-anchor-bg')
      }
    },
    /* 更新节点，包含文本 */
    update(cfg, node) {
      const model = node.get('model')
      const { attrs } = node.get('keyShape')
      // const text = node.get('group').getItem('node-text');
      const item = node.get('group').get('children')[0]

      setTimeout(() => {
        // 更新节点属性
        item.attr({ ...attrs, ...model.style })
      })
    },
    afterUpdate(cfg, node) {
      /* const group = node.get('group')

      console.log(group)
      // group.clearAnchor(group)
      // 重新绘制锚点
      this.initAnchor(cfg, group)*/
      // console.log('+=======================节点更新==============')
    },
    /* 设置节点的状态，主要是交互状态，业务状态请在 draw 方法中实现 */
    setState(name, value, item) {
      const buildInEvents = [
        'anchorShow',
        'anchorActived',
        'nodeState',
        'nodeState:default',
        'nodeState:selected',
        'nodeState:hover',
        'nodeOnDragStart',
        'nodeOnDrag',
        'nodeOnDragEnd',
        // 编辑模式下
        'editShow',
        'rotateShow',
        'rotateIcon'
      ]
      const group = item.getContainer()
      if (group.get('destroyed')) return
      if (buildInEvents.includes(name)) {
        // 内部this绑定到了当前item实例
        itemEvents[name].call(this, value, group)
      }
    },
    /* 获取锚点（相关边的连入点） */
    getAnchorPoints(cfg) {
      return cfg.anchorPoints || [
        [0.5, 0],
        [1, 0.5],
        [0.5, 1],
        [0, 0.5]
      ]
    }
  }, 'rect')
}
